package ch.coredump.tagcloud.data.appstate;

import java.util.Hashtable;

import javafx.stage.Stage;

/**
 * Class for Managing different Scenes which are represented by AppStates.
 */
public class AppStateManager {
	// list of managed states
	private Hashtable<AppStates, AbstractAppState> states = new Hashtable<AppStates, AbstractAppState>();
	// currently active Appstate or null
	private AbstractAppState current;

	// the stage to manage
	private Stage stage;

	/**
	 * exits the current and activates the given AppState.
	 * 
	 * @param state
	 */
	public void switchTo(AppStates state) {
		// exit current AppState
		if (current != null) {
			current.exit();
		}

		// create the new AppState
		current = getAppState(state);

		// activate new AppState
		current.doActivate();

		// set the AppState's scene on the pimary stage
		stage.setScene(current.getScene());
	}

	/**
	 * @param state
	 *            state to return
	 * @return the given AppState
	 */
	private AbstractAppState getAppState(AppStates state) {
		AbstractAppState as = states.get(state);
		if (as == null) {
			as = createAppState(state);
			states.put(state, as);
		}
		return as;
	}

	private AbstractAppState createAppState(AppStates state) {
		AbstractAppState as = null;
		switch (state) {
		case INTRO:
			as = new AppStateIntro(this);
			break;
		case MENU:
			as = new AppStateMenu(this);
			break;
		case MAIN:
			as = new AppStateMain(this);
			break;
		case EXIT:
			as = new AppStateExit(this);
			break;
		default:
			throw new RuntimeException("unknown state");
		}

		as.init();

		return as;
	}

	/**
	 * Sets the Stage to manage.
	 * 
	 * @param primaryStage
	 */
	public void setStage(Stage primaryStage) {
		this.stage = primaryStage;
	}

	public Stage getStage() {
		return stage;
	}

	public static AppStateManager getInstance() {
		return AppStateManagerInstance.INSTANCE;
	}

	/**
	 * private class containing the AppStatemanager instance.
	 */
	private static final class AppStateManagerInstance {
		private static final AppStateManager INSTANCE = new AppStateManager();
	}

}
